package com.stx.jeepay.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.stx.jeepay.core.dao.PayInterfaceConfigDao;
import com.stx.jeepay.core.entity.MchAppEntity;
import com.stx.jeepay.core.entity.MchInfoEntity;
import com.stx.jeepay.core.entity.PayInterfaceConfigEntity;
import com.stx.jeepay.core.entity.PayInterfaceDefineEntity;
import com.stx.jeepay.core.enums.ApiCodeEnum;
import com.stx.jeepay.core.enums.CS;
import com.stx.jeepay.core.expection.BizException;
import com.stx.jeepay.core.service.MchAppService;
import com.stx.jeepay.core.service.MchInfoService;
import com.stx.jeepay.core.service.PayInterfaceConfigService;
import com.stx.jeepay.core.service.PayInterfaceDefineService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;


@Service("payInterfaceConfigService")
public class PayInterfaceConfigServiceImpl extends ServiceImpl<PayInterfaceConfigDao, PayInterfaceConfigEntity> implements PayInterfaceConfigService {

    @Autowired
    private PayInterfaceDefineService payInterfaceDefineService;

    @Autowired
    private MchInfoService mchInfoService;

    @Autowired
    private MchAppService mchAppService;

    @Override
    public List<PayInterfaceDefineEntity> selectAllPayIfConfigListByAppId(String appId) {
        MchAppEntity mchApp = mchAppService.getById(appId);
        if (mchApp == null || mchApp.getState() != CS.YES) {
            throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SELETE);
        }
        MchInfoEntity mchInfo = mchInfoService.getById(mchApp.getMchNo());
        if (mchInfo == null || mchInfo.getState() != CS.YES) {
            throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SELETE);
        }
        // 支付定义列表
        LambdaQueryWrapper<PayInterfaceDefineEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PayInterfaceDefineEntity::getState, CS.YES);

        Map<String, PayInterfaceConfigEntity> isvPayConfigMap = new HashMap<>(); // 服务商支付参数配置集合

        // 根据商户类型，添加接口是否支持该商户类型条件
        if (mchInfo.getType() == CS.MCH_TYPE_NORMAL) {
            queryWrapper.eq(PayInterfaceDefineEntity::getIsMchMode, CS.YES); // 支持普通商户模式
        }
        if (mchInfo.getType() == CS.MCH_TYPE_ISVSUB) {
            queryWrapper.eq(PayInterfaceDefineEntity::getIsIsvMode, CS.YES); // 支持服务商模式
            // 商户类型为特约商户，服务商应已经配置支付参数
            List<PayInterfaceConfigEntity> isvConfigList = list(new LambdaQueryWrapper<PayInterfaceConfigEntity>()
                    .eq(PayInterfaceConfigEntity::getInfoId, mchInfo.getIsvNo())
                    .eq(PayInterfaceConfigEntity::getInfoType, CS.INFO_TYPE_ISV)
                    .eq(PayInterfaceConfigEntity::getState, CS.YES)
                    .ne(PayInterfaceConfigEntity::getIfParams, "")
                    .isNotNull(PayInterfaceConfigEntity::getIfParams));

            for (PayInterfaceConfigEntity config : isvConfigList) {
                config.addExt("mchType", mchInfo.getType());
                isvPayConfigMap.put(config.getIfCode(), config);
            }
        }
        List<PayInterfaceDefineEntity> defineList = payInterfaceDefineService.list(queryWrapper);

        // 支付参数列表
        LambdaQueryWrapper<PayInterfaceConfigEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PayInterfaceConfigEntity::getInfoId, appId);
        wrapper.eq(PayInterfaceConfigEntity::getInfoType, CS.INFO_TYPE_MCH_APP);
        List<PayInterfaceConfigEntity> configList = list(wrapper);

        for (PayInterfaceDefineEntity define : defineList) {
            define.addExt("mchType", mchInfo.getType()); // 所属商户类型

            for (PayInterfaceConfigEntity config : configList) {
                if (define.getIfCode().equals(config.getIfCode())) {
                    define.addExt("ifConfigState", config.getState()); // 配置状态
                }
            }
            if (mchInfo.getType() == CS.MCH_TYPE_ISVSUB && isvPayConfigMap.get(define.getIfCode()) == null) {
                define.addExt("subMchIsvConfig", CS.NO); // 特约商户，服务商支付参数的配置状态，0表示未配置
            }
        }
        return defineList;
    }

    @Override
    public PayInterfaceConfigEntity getByInfoIdAndIfCode(Byte infoType, String infoId, String ifCode) {
        return getOne(new LambdaQueryWrapper<PayInterfaceConfigEntity>()
                .eq(PayInterfaceConfigEntity::getInfoType, infoType)
                .eq(PayInterfaceConfigEntity::getInfoId, infoId)
                .eq(PayInterfaceConfigEntity::getIfCode, ifCode));
    }

    @Override
    public List<PayInterfaceDefineEntity> selectAllPayIfConfigListByIsvNo(Byte infoType, String infoId) {
        // 支付定义列表
        LambdaQueryWrapper<PayInterfaceDefineEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PayInterfaceDefineEntity::getState, CS.YES);
        queryWrapper.eq(PayInterfaceDefineEntity::getIsIsvMode, CS.YES);

        List<PayInterfaceDefineEntity> defineList = payInterfaceDefineService.list(queryWrapper);

        // 支付参数列表
        LambdaQueryWrapper<PayInterfaceConfigEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PayInterfaceConfigEntity::getInfoId, infoId);
        wrapper.eq(PayInterfaceConfigEntity::getInfoType, infoType);
        List<PayInterfaceConfigEntity> configList = this.list(wrapper);

        for (PayInterfaceDefineEntity define : defineList) {
            for (PayInterfaceConfigEntity config : configList) {
                if (define.getIfCode().equals(config.getIfCode())) {
                    define.addExt("ifConfigState", config.getState()); // 配置状态
                }
            }

        }
        return defineList;
    }

    /**
     * 查询商户app使用已正确配置了通道信息
     */
    @Override
    public boolean mchAppHasAvailableIfCode(String appId, String ifCode) {
        return count(new LambdaQueryWrapper<PayInterfaceConfigEntity>()
                .eq(PayInterfaceConfigEntity::getIfCode, ifCode)
                .eq(PayInterfaceConfigEntity::getState, CS.PUB_USABLE)
                .eq(PayInterfaceConfigEntity::getInfoId, appId)
                .eq(PayInterfaceConfigEntity::getInfoType, CS.INFO_TYPE_MCH_APP)) > 0;
    }
}